# -*- coding:utf8 -*-

import shapefile

from shapely.geometry import asPolygon

import os
import json
import urllib2

import sys
reload(sys)
sys.setdefaultencoding('utf8')

import time
from functools import wraps
def retry(ExceptionToCheck, tries=4, delay=1, backoff=2, logger=None):
    def deco_retry(f):

        @wraps(f)
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            while mtries > 1:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck, e:
                    msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
                    if logger:
                        logger.warning(msg)
                    else:
                        print 'WARNING:', msg
                    time.sleep(mdelay)
                    mtries -= 1
                    mdelay *= backoff
            return f(*args, **kwargs)

        return f_retry

    return deco_retry

access_token="1MNrcRmU3mZgCuKgHukfIt9XF2GblvcC"
access_token_gd="2b7de0dc015fe07cbc4125947b8f7c04"


@retry(Exception)
def request(uri, **kvargs):
    # if 'ak' not in kvargs: kvargs['ak'] = access_token
    url = '{}{}{}'.format(uri,
                          '&' if '?' in uri else '?',
                          '&'.join('{}={}'.format(k, kvargs[k]) for k in kvargs))
    content = urllib2.urlopen(url).read()
    result = json.loads(content)
    if result['status'] == kvargs['rescode']:
        return result[kvargs['resdata']]
    else:
        raise urllib2.URLError(result['status'])

def concat(coords,splitchar):
    if isinstance(coords[0], (list, tuple)):
        return splitchar.join(concat(c,splitchar) for c in coords)
    else:
        return ','.join(str(c) for c in coords)

def convert(coords, ak = None, reverse = False,apitype='bd'):
    uri_base = "http://api.map.baidu.com/geoconv/v1/"
    url_gd = 'https://restapi.amap.com/v3/assistant/coordinate/convert'
    #if ak is None: ak = access_token
    chunk = 100
    coords = [coords[i:i+chunk] for i in range(0, len(coords), chunk)]
    result = []
    for c in coords:
        #uri = "{}?coords={}&ak={}".format(uri_base, concat(c), ak)
        #result.extend(request(uri))
        if reverse:
            res = request(uri_base+"?from=3", coords=concat(c))
            result.extend((2*coords[i][0]-r['x'],2*coords[i][1]-r['y']) for i,r in enumerate(res))
        else:
            if(apitype == 'gd'):
                res = request(url_gd, locations=concat(c,'|'),key=access_token_gd,rescode=u'1',resdata='locations',coordsys='gps')
                result.extend((float(r.split(',')[0]),float(r.split(',')[1])) for r in res.split(';'))
            else:
                res = request(uri_base, coords=concat(c,';'),ak=access_token,rescode=0,resdata='result')
                result.extend((r['x'],r['y']) for r in res)
    return result

def TransformFeature(datasource, target,apitype='bd'):
    extlist = ['.prj', '.cpg']
    with shapefile.Reader(datasource) as shpfile, shapefile.Writer(target) as outfile:
        outfile.shapeType = shpfile.shapeType
        outfile.fields = shpfile.fields[1:]
        outfile.autoBalance = 1
        for data in shpfile.iterShapeRecords():
            outfile.record(*data.record)
            #outfile.shape(data.shape)
            points = convert(data.shape.points,apitype)
            print 'Convert {} Points.'.format(len(points))
            parts = data.shape.parts
            shape=[points[p: parts[i+1] if i+1 < len(parts) else len(points)] for i, p in enumerate(parts)]
            outfile.poly(shape)
        for ext in extlist:
            extfile = shpfile.shapeName + ext
            if os.path.exists(extfile):
                with open(extfile, 'rb') as ifile, open(outfile.target + ext, 'wb') as ofile:
                    ofile.write(ifile.read())
    return target

if __name__ == '__main__':
    datasource = ur'D:\\desktop\\第七次人口普查\\滨州地址比对\\371625002.shp'
    output = ur'D:\\desktop\\第七次人口普查\\滨州地址比对\\371625002_gd.shp'
    TransformFeature(datasource, output)
